home *** CD-ROM | disk | FTP | other *** search
- Subject: Small C compiler version C3.0R1.1 (part 1 of 3)
- Newsgroups: mod.sources
- Approved: jpn@panda.UUCP
-
- Mod.sources: Volume 5, Issue 7
- Submitted by: genrad!linus!mnetor!clewis (Chris Lewis)
-
- There've been quite a few requests for this via net.micro.cpm, so's I
- thought I'd post it thru mod.sources. This is Ron Cain's original Small
- C compiler, but highly extended. Included are code generators for 8080,
- 6809, 68000, and VAX, as well as run-time support for 8080 CPM, VAX BSD4.1,
- and a FLEX 6809 environment. See the README for a description of Small C's
- limitations.
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # README
- # M_README
- # Makefile
- # Makefile.bsd
- # code8080.c
- # codeas09.c
- # codem68k.c
- # codevax.c
- # data.c
- # data.h
- # This archive created: Sun May 18 18:28:42 1986
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'README'" '(2959 characters)'
- if test -f 'README'
- then
- echo shar: will not over-write existing file "'README'"
- else
- cat << \SHAR_EOF > 'README'
- Small C version C3.0R1.1
- (SCC3)
-
- Chris Lewis
-
- This directory contains the source for a version of Ron Cain's Small C
- compiler that I have heavily modified - beyond the Small-C V2.0 later
- published in Dr. Dobbs. This compiler generates assembler source code that
- needs to be assembled and linked to make a running program.
-
- Small C is a public domain compiler for a subset of C. The main things
- lacking are "#if", structs/unions, doubles/floats/longs and more than
- one level of indirection. Even so, it's powerful enough to be able to
- compile itself. It's also lots of fun to play around with. It could
- use lots of more work (eg: a real scanner), but what the heck...
- Retargetting the compiler requires only relinking the frontend with a new
- code generator.
-
- Code generators for 6809 (MIT UNIX-like assembler), M68K (Motorola V/68 UNIX
- assembler), VAX (BSD 4.1 assembler), and 8080 (RMAC assembler) are provided.
-
- Users having access to System V make should be able to use the Makefile
- without any modification except for INCDIR and LIBDIR (where you'd like
- to put the compiler itself).
-
- Users not having access to System V will probably have to rewrite the Makefile.
- [ I have provided a Makefile that seems to work with bsd systems - mod]
-
- WARNING: you will probably see a great deal of compilation warnings when
- you compile this compiler with a "real" UNIX C. Don't worry - this is
- *perfectly* normal - Small C is a subset of real C, and in order to
- keep the compiler in this subset you have to bend the rules somewhat.
- The only time where this might cause a problem is where pointers are
- "different" from ints (ie: different length or on non-byte-addressible
- machines). Small C assumes that ints are the same as pointers.
-
- Invocation:
- scc<6809|vax|m68k|8080> filename
-
- There are other options available - see main.c for details.
-
- The code generated by these compilers need a run-time support library
- for two things: operations that are "hard" on a particular processor
- (eg: 16 bit multiply on an 8080), or O/S interface (vax is BSD 4.1,
- 6809 is FLEX, 8080 is CPM, never had one for M68k).
-
- Status: the 6809, VAX and 8080 versions work last I checked - a problem or
- two may have crept in during the implementation of the compile/assemble/and
- link code for machines that support it. The M68k version has never been
- tested. I don't have a Pyramid version because Pyrcorp seems reluctant
- to publish instruction set information.
-
- So you want to write a new coder do you? Well, it's easy - read the
- comments in one of the coders. You should not have to modify *any* of
- the existing files, just write a new codexxx.c file. Please contact
- me if you run into trouble. I would be greatly interested in any new
- coders or bug reports in the compilers. As far as I am aware, the
- major restriction on porting this thing for different targets is that
- pointers and integers *must* be the same length, alignment, and be
- interchangeable.
- SHAR_EOF
- if test 2959 -ne "`wc -c < 'README'`"
- then
- echo shar: error transmitting "'README'" '(should have been 2959 characters)'
- fi
- fi
- echo shar: extracting "'M_README'" '(550 characters)'
- if test -f 'M_README'
- then
- echo shar: will not over-write existing file "'M_README'"
- else
- cat << \SHAR_EOF > 'M_README'
- *** Moderator's README ***
-
- This directory contains the base source code for the smallC compiler
- (actually three versions: the 8080, 6809 and vax code generators are
- here also.)
-
- The "includes" directory contains headers which are intended to be included in
- user programs - the place where these files reside should be set in the Makefile
- as INCDIR. The directories "6809", "8080", and "vax" contain runtime support
- for the respective compilers. The directory "lib" contains the source code
- for some common C library functions (portable ones).
- SHAR_EOF
- if test 550 -ne "`wc -c < 'M_README'`"
- then
- echo shar: error transmitting "'M_README'" '(should have been 550 characters)'
- fi
- fi
- echo shar: extracting "'Makefile'" '(1429 characters)'
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- cat << \SHAR_EOF > 'Makefile'
- # Requires System V make
- # @(#)Makefile 1.5 86/05/13
- .SUFFIXES: .o .c .c~ .h .h~
- .PRECIOUS: scclib.a
- # You'll probabably want to change these. These are used by the compilers# to figure out where the include files should go.
- TARGDIR = /u/clewis/lib
- INCDIR = "/u/clewis/src/scc/include/"
-
- INSTFLAGS = -DINCDIR=$(INCDIR)
- CFLAGS = '$(INSTFLAGS)' -O
- AR = ar
- ARFLAGS = rv
-
- LIB = scclib.a
-
- FE = $(LIB)(data.o) \
- $(LIB)(error.o) \
- $(LIB)(expr.o) \
- $(LIB)(function.o) \
- $(LIB)(gen.o) \
- $(LIB)(io.o) \
- $(LIB)(lex.o) \
- $(LIB)(main.o) \
- $(LIB)(preproc.o) \
- $(LIB)(primary.o) \
- $(LIB)(stmt.o) \
- $(LIB)(sym.o) \
- $(LIB)(while.o)
-
- all: scc8080 sccas09 sccvax sccm68k
-
- $(FE) code8080.o codeas09.o codevax.o codem68k.o: defs.h data.h
-
- install: all
- mv sccvax scc8080 sccas09 sccm68k $(TARGDIR)
-
- #Alternately, you may have to do an lorder
- $(LIB): $(FE)
- -ranlib $(LIB)
- -ucb ranlib $(LIB)
-
- scc8080: code8080.o $(LIB)
- $(CC) -o scc8080 $(CFLAGS) $(LIB) code8080.o
-
- sccas09: codeas09.o $(LIB)
- $(CC) -o sccas09 $(CFLAGS) $(LIB) codeas09.o
-
- sccvax: codevax.o $(LIB)
- $(CC) -o sccvax $(CFLAGS) $(LIB) codevax.o
-
- sccm68k: codem68k.o $(LIB)
- $(CC) -o sccm68k $(CFLAGS) $(LIB) codem68k.o
-
- print:
- pr -n defs.h data.h data.c error.c expr.c function.c gen.c \
- io.c lex.c main.c preproc.c primary.c stmt.c \
- sym.c while.c code*.c | lp
- clean:
- rm -f $(LIB) code8080.o codeas09.o codevax.o codem68k.o \
- sccvax scc8080 sccas09 sccm68k
- SHAR_EOF
- if test 1429 -ne "`wc -c < 'Makefile'`"
- then
- echo shar: error transmitting "'Makefile'" '(should have been 1429 characters)'
- fi
- fi
- echo shar: extracting "'Makefile.bsd'" '(1359 characters)'
- if test -f 'Makefile.bsd'
- then
- echo shar: will not over-write existing file "'Makefile.bsd'"
- else
- cat << \SHAR_EOF > 'Makefile.bsd'
- # I couldn't get the supplied makefile to work, so I wrote one for
- # BSD systems - John Nelson, moderator, mod.sources
- #
- # You'll probabably want to change these. These are used by the compilers# to figure out where the include files should go.
- TARGDIR = /u/clewis/lib
- INCDIR = "/u/clewis/src/scc/include/"
-
- INSTFLAGS = -DINCDIR=$(INCDIR)
- CFLAGS = '$(INSTFLAGS)' -O
- AR = ar
- ARFLAGS = rv
-
- LIB = scclib.a
-
- FE = data.o \
- error.o \
- expr.o \
- function.o \
- gen.o \
- io.o \
- lex.o \
- main.o \
- preproc.o \
- primary.o \
- stmt.o \
- sym.o \
- while.o
-
- all: scc8080 sccas09 sccvax sccm68k
-
- $(FE) code8080.o codeas09.o codevax.o codem68k.o: defs.h data.h
-
- install: all
- mv sccvax scc8080 sccas09 sccm68k $(TARGDIR)
-
- #Alternately, you may have to do an lorder
- $(LIB): $(FE)
- -rm $@
- ar q $@ $(FE)
- -ranlib $(LIB)
-
- scc8080: code8080.o $(LIB)
- $(CC) -o scc8080 $(CFLAGS) $(LIB) code8080.o
-
- sccas09: codeas09.o $(LIB)
- $(CC) -o sccas09 $(CFLAGS) $(LIB) codeas09.o
-
- sccvax: codevax.o $(LIB)
- $(CC) -o sccvax $(CFLAGS) $(LIB) codevax.o
-
- sccm68k: codem68k.o $(LIB)
- $(CC) -o sccm68k $(CFLAGS) $(LIB) codem68k.o
-
- print:
- pr -n defs.h data.h data.c error.c expr.c function.c gen.c \
- io.c lex.c main.c preproc.c primary.c stmt.c \
- sym.c while.c code*.c | lp
- clean:
- rm -f $(LIB) code8080.o codeas09.o codevax.o codem68k.o \
- sccvax scc8080 sccas09 sccm68k
- SHAR_EOF
- if test 1359 -ne "`wc -c < 'Makefile.bsd'`"
- then
- echo shar: error transmitting "'Makefile.bsd'" '(should have been 1359 characters)'
- fi
- fi
- echo shar: extracting "'code8080.c'" '(9671 characters)'
- if test -f 'code8080.c'
- then
- echo shar: will not over-write existing file "'code8080.c'"
- else
- cat << \SHAR_EOF > 'code8080.c'
- /* File code8080.c: 2.2 (84/08/31,10:05:09) */
- /*% cc -O -c %
- *
- */
-
- #include <stdio.h>
- #include "defs.h"
- #include "data.h"
-
- /* Define ASNM and LDNM to the names of the assembler and linker
- respectively */
-
- /*
- * Some predefinitions:
- *
- * INTSIZE is the size of an integer in the target machine
- * BYTEOFF is the offset of an byte within an integer on the
- * target machine. (ie: 8080,pdp11 = 0, 6809 = 1,
- * 360 = 3)
- * This compiler assumes that an integer is the SAME length as
- * a pointer - in fact, the compiler uses INTSIZE for both.
- */
- #define INTSIZE 2
- #define BYTEOFF 0
-
- /*
- * print all assembler info before any code is generated
- *
- */
- header ()
- {
- outstr ("; Small C 8080;\n;\tCoder (2.4,84/11/27)\n;");
- FEvers();
- nl ();
- ol ("extrn ?gchar,?gint,?pchar,?pint,?bool");
- ol ("extrn ?sxt");
- ol ("extrn ?or,?and,?xor");
- ol ("extrn ?eq,?ne,?gt,?le,?ge,?lt,?uge,?ult,?ugt,?ule");
- ol ("extrn ?asr,?asl");
- ol ("extrn ?sub,?neg,?com,?lneg,?mul,?div");
- ol ("extrn ?case");
- }
-
- nl ()
- {
- outbyte (EOL);
- }
- initmac()
- {
- defmac("cpm\t1");
- defmac("I8080\t1");
- defmac("RMAC\t1");
- defmac("smallc\t1");
- }
-
- galign(t)
- int t;
- {
- return(t);
- }
-
- /*
- * return size of an integer
- */
- intsize() {
- return(INTSIZE);
- }
-
- /*
- * return offset of ls byte within word
- * (ie: 8080 & pdp11 is 0, 6809 is 1, 360 is 3)
- */
- byteoff() {
- return(BYTEOFF);
- }
-
- /*
- * Output internal generated label prefix
- */
- olprfix() {
- outbyte('?');
- }
-
- /*
- * Output a label definition terminator
- */
- col ()
- {
- outbyte (58);
- }
-
- /*
- * begin a comment line for the assembler
- *
- */
- comment ()
- {
- outbyte (';');
- }
-
- /*
- * Emit user label prefix
- */
- prefix ()
- {
- }
-
-
- /*
- * print any assembler stuff needed after all code
- *
- */
- trailer ()
- {
- ol ("end");
- }
-
- /*
- * function prologue
- */
- prologue ()
- {
- }
-
- /*
- * text (code) segment
- */
- gtext ()
- {
- ol ("cseg");
- }
-
- /*
- * data segment
- */
- gdata ()
- {
- ol ("dseg");
- }
-
- /*
- * Output the variable symbol at scptr as an extrn or a public
- */
- ppubext(scptr) char *scptr; {
- if (cptr[STORAGE] == STATIC) return;
- ot (scptr[STORAGE] == EXTERN ? "extrn\t" : "public\t");
- prefix ();
- outstr (scptr);
- nl();
- }
-
- /*
- * Output the function symbol at scptr as an extrn or a public
- */
- fpubext(scptr) char *scptr; {
- if (scptr[STORAGE] == STATIC) return;
- ot (scptr[OFFSET] == FUNCTION ? "public\t" : "extrn\t");
- prefix ();
- outstr (scptr);
- nl ();
- }
-
- /*
- * Output a decimal number to the assembler file
- */
- onum(num) int num; {
- outdec(num); /* pdp11 needs a "." here */
- }
-
-
- /*
- * fetch a static memory cell into the primary register
- */
- getmem (sym)
- char *sym;
- {
- if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) {
- ot ("lda\t");
- outstr (sym + NAME);
- nl ();
- gcall ("?sxt");
- } else {
- ot ("lhld\t");
- outstr (sym + NAME);
- nl ();
- }
- }
-
- /*
- * fetch the address of the specified symbol into the primary register
- *
- */
- getloc (sym)
- char *sym;
- {
- immed ();
- if (sym[STORAGE] == LSTATIC) {
- printlabel(glint(sym));
- nl();
- } else {
- outdec (glint(sym) - stkp);
- nl ();
- ol ("dad\tsp");
- }
- }
-
- /*
- * store the primary register into the specified static memory cell
- *
- */
- putmem (sym)
- char *sym;
- {
- if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) {
- ol ("mov\ta,l");
- ot ("sta\t");
- } else
- ot ("shld\t");
- outstr (sym + NAME);
- nl ();
- }
-
- /*
- * store the specified object type in the primary register
- * at the address on the top of the stack
- *
- */
- putstk (typeobj)
- char typeobj;
- {
- gpop ();
- if (typeobj == CCHAR)
- gcall ("?pchar");
- else
- gcall ("?pint");
- }
-
- /*
- * fetch the specified object type indirect through the primary
- * register into the primary register
- *
- */
- indirect (typeobj)
- char typeobj;
- {
- if (typeobj == CCHAR)
- gcall ("?gchar");
- else
- gcall ("?gint");
- }
-
- /*
- * swap the primary and secondary registers
- *
- */
- swap ()
- {
- ol ("xchg");
- }
-
- /*
- * print partial instruction to get an immediate value into
- * the primary register
- *
- */
- immed ()
- {
- ot ("lxi\th,");
- }
-
- /*
- * push the primary register onto the stack
- *
- */
- gpush ()
- {
- ol ("push\th");
- stkp = stkp - INTSIZE;
- }
-
- /*
- * pop the top of the stack into the secondary register
- *
- */
- gpop ()
- {
- ol ("pop\td");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * swap the primary register and the top of the stack
- *
- */
- swapstk ()
- {
- ol ("xthl");
- }
-
- /*
- * call the specified subroutine name
- *
- */
- gcall (sname)
- char *sname;
- {
- ot ("call\t");
- outstr (sname);
- nl ();
- }
-
- /*
- * return from subroutine
- *
- */
- gret ()
- {
- ol ("ret");
- }
-
- /*
- * perform subroutine call to value on top of stack
- *
- */
- callstk ()
- {
- immed ();
- outstr ("$+5");
- nl ();
- swapstk ();
- ol ("pchl");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * jump to specified internal label number
- *
- */
- jump (label)
- int label;
- {
- ot ("jmp\t");
- printlabel (label);
- nl ();
- }
-
- /*
- * test the primary register and jump if false to label
- *
- */
- testjump (label, ft)
- int label,
- ft;
- {
- ol ("mov\ta,h");
- ol ("ora\tl");
- if (ft)
- ot ("jnz\t");
- else
- ot ("jz\t");
- printlabel (label);
- nl ();
- }
-
- /*
- * print pseudo-op to define a byte
- *
- */
- defbyte ()
- {
- ot ("db\t");
- }
-
- /*
- * print pseudo-op to define storage
- *
- */
- defstorage ()
- {
- ot ("ds\t");
- }
-
- /*
- * print pseudo-op to define a word
- *
- */
- defword ()
- {
- ot ("dw\t");
- }
-
- /*
- * modify the stack pointer to the new value indicated
- *
- */
- modstk (newstkp)
- int newstkp;
- {
- int k;
-
- k = galign(newstkp - stkp);
- if (k == 0)
- return (newstkp);
- if (k > 0) {
- if (k < 7) {
- if (k & 1) {
- ol ("inx\tsp");
- k--;
- }
- while (k) {
- ol ("pop\tb");
- k = k - INTSIZE;
- }
- return (newstkp);
- }
- } else {
- if (k > -7) {
- if (k & 1) {
- ol ("dcx\tsp");
- k++;
- }
- while (k) {
- ol ("push\tb");
- k = k + INTSIZE;
- }
- return (newstkp);
- }
- }
- swap ();
- immed ();
- outdec (k);
- nl ();
- ol ("dad\tsp");
- ol ("sphl");
- swap ();
- return (newstkp);
- }
-
- /*
- * multiply the primary register by INTSIZE
- */
- gaslint ()
- {
- ol ("dad\th");
- }
-
- /*
- * divide the primary register by INTSIZE
- */
- gasrint()
- {
- gpush(); /* push primary in prep for gasr */
- immed ();
- onum (1);
- nl ();
- gasr (); /* divide by two */
- }
-
- /*
- * Case jump instruction
- */
- gjcase() {
- ot ("jmp\t?case");
- nl ();
- }
-
- /*
- * add the primary and secondary registers
- * if lval2 is int pointer and lval is not, scale lval
- */
- gadd (lval,lval2) int *lval,*lval2;
- {
- gpop ();
- if (dbltest (lval2, lval)) {
- swap ();
- gaslint ();
- swap ();
- }
- ol ("dad\td");
- }
-
- /*
- * subtract the primary register from the secondary
- *
- */
- gsub ()
- {
- gpop ();
- gcall ("?sub");
- }
-
- /*
- * multiply the primary and secondary registers
- * (result in primary)
- *
- */
- gmult ()
- {
- gpop();
- gcall ("?mul");
- }
-
- /*
- * divide the secondary register by the primary
- * (quotient in primary, remainder in secondary)
- *
- */
- gdiv ()
- {
- gpop();
- gcall ("?div");
- }
-
- /*
- * compute the remainder (mod) of the secondary register
- * divided by the primary register
- * (remainder in primary, quotient in secondary)
- *
- */
- gmod ()
- {
- gdiv ();
- swap ();
- }
-
- /*
- * inclusive 'or' the primary and secondary registers
- *
- */
- gor ()
- {
- gpop();
- gcall ("?or");
- }
-
- /*
- * exclusive 'or' the primary and secondary registers
- *
- */
- gxor ()
- {
- gpop();
- gcall ("?xor");
- }
-
- /*
- * 'and' the primary and secondary registers
- *
- */
- gand ()
- {
- gpop();
- gcall ("?and");
- }
-
- /*
- * arithmetic shift right the secondary register the number of
- * times in the primary register
- * (results in primary register)
- *
- */
- gasr ()
- {
- gpop();
- gcall ("?asr");
- }
-
- /*
- * arithmetic shift left the secondary register the number of
- * times in the primary register
- * (results in primary register)
- *
- */
- gasl ()
- {
- gpop ();
- gcall ("?asl");
- }
-
- /*
- * two's complement of primary register
- *
- */
- gneg ()
- {
- gcall ("?neg");
- }
-
- /*
- * logical complement of primary register
- *
- */
- glneg ()
- {
- gcall ("?lneg");
- }
-
- /*
- * one's complement of primary register
- *
- */
- gcom ()
- {
- gcall ("?com");
- }
-
- /*
- * Convert primary value into logical value (0 if 0, 1 otherwise)
- *
- */
- gbool ()
- {
- gcall ("?bool");
- }
-
- /*
- * increment the primary register by 1 if char, INTSIZE if
- * int
- */
- ginc (lval) int lval[];
- {
- ol ("inx\th");
- if (lval[2] == CINT)
- ol ("inx\th");
- }
-
- /*
- * decrement the primary register by one if char, INTSIZE if
- * int
- */
- gdec (lval) int lval[];
- {
- ol ("dcx\th");
- if (lval[2] == CINT)
- ol("dcx\th");
- }
-
- /*
- * following are the conditional operators.
- * they compare the secondary register against the primary register
- * and put a literl 1 in the primary if the condition is true,
- * otherwise they clear the primary register
- *
- */
-
- /*
- * equal
- *
- */
- geq ()
- {
- gpop();
- gcall ("?eq");
- }
-
- /*
- * not equal
- *
- */
- gne ()
- {
- gpop();
- gcall ("?ne");
- }
-
- /*
- * less than (signed)
- *
- */
- glt ()
- {
- gpop();
- gcall ("?lt");
- }
-
- /*
- * less than or equal (signed)
- *
- */
- gle ()
- {
- gpop();
- gcall ("?le");
- }
-
- /*
- * greater than (signed)
- *
- */
- ggt ()
- {
- gpop();
- gcall ("?gt");
- }
-
- /*
- * greater than or equal (signed)
- *
- */
- gge ()
- {
- gpop();
- gcall ("?ge");
- }
-
- /*
- * less than (unsigned)
- *
- */
- gult ()
- {
- gpop();
- gcall ("?ult");
- }
-
- /*
- * less than or equal (unsigned)
- *
- */
- gule ()
- {
- gpop();
- gcall ("?ule");
- }
-
- /*
- * greater than (unsigned)
- *
- */
- gugt ()
- {
- gpop();
- gcall ("?ugt");
- }
-
- /*
- * greater than or equal (unsigned)
- *
- */
- guge ()
- {
- gpop();
- gcall ("?uge");
- }
-
- inclib() {
- #ifdef cpm
- return("B:");
- #endif
- #ifdef unix
- return(INCDIR);
- #endif
- }
-
- /* Squirrel away argument count in a register that modstk
- doesn't touch.
- */
-
- gnargs(d)
- int d; {
- ot ("mvi\ta,");
- onum(d);
- nl ();
- }
-
- assemble(s)
- char *s; {
- #ifdef ASNM
- char buf[100];
- strcpy(buf, ASNM);
- strcat(buf, " ");
- strcat(buf, s);
- buf[strlen(buf)-1] = 's';
- return(system(buf));
- #else
- return(0);
- #endif
- }
-
- link() {
- #ifdef LDNM
- fputs("I don't know how to link files yet\n", stderr);
- #else
- return(0);
- #endif
- }
- SHAR_EOF
- if test 9671 -ne "`wc -c < 'code8080.c'`"
- then
- echo shar: error transmitting "'code8080.c'" '(should have been 9671 characters)'
- fi
- fi
- echo shar: extracting "'codeas09.c'" '(9534 characters)'
- if test -f 'codeas09.c'
- then
- echo shar: will not over-write existing file "'codeas09.c'"
- else
- cat << \SHAR_EOF > 'codeas09.c'
- /* File codeas09.c: 2.2 (84/08/31,10:05:13) */
- /*% cc -O -c %
- *
- */
-
- #include <stdio.h>
- #include "defs.h"
- #include "data.h"
-
- /* Define ASNM and LDNM to the names of the assembler and linker
- respectively */
-
- /*
- * Some predefinitions:
- *
- * INTSIZE is the size of an integer in the target machine
- * BYTEOFF is the offset of an byte within an integer on the
- * target machine. (ie: 8080,pdp11 = 0, 6809 = 1,
- * 360 = 3)
- * This compiler assumes that an integer is the SAME length as
- * a pointer - in fact, the compiler uses INTSIZE for both.
- */
- #define INTSIZE 2
- #define BYTEOFF 1
-
- /*
- * print all assembler info before any code is generated
- *
- */
- header ()
- {
- outstr("|\tSmall C MC6809\n|\tCoder (2.4,84/11/27)\n|");
- FEvers();
- nl ();
- ol (".globl\tsmul,sdiv,smod,asr,asl,neg,lneg,case");
- ol (".globl\teq,ne,lt,le,gt,ge,ult,ule,ugt,uge,bool");
- }
- nl ()
- {
- outbyte (EOL);
- }
-
- initmac() {
- defmac("mc6809\t1");
- defmac("mitas09\t1");
- defmac("smallc\t1");
- }
-
- galign(t)
- int t;
- {
- return (t);
- }
-
-
- /*
- * return size of an integer
- */
- intsize() {
- return(INTSIZE);
- }
-
- /*
- * return offset of ls byte within word
- * (ie: 8080 & pdp11 is 0, 6809 is 1, 360 is 3)
- */
- byteoff() {
- return(BYTEOFF);
- }
-
- /*
- * Output internal generated label prefix
- */
- olprfix() {
- outstr("LL");
- }
-
- /*
- * Output a label definition terminator
- */
- col ()
- {
- outstr ("=.\n");
- }
-
- /*
- * begin a comment line for the assembler
- *
- */
- comment ()
- {
- outbyte ('|');
- }
-
- /*
- * Output a prefix in front of user labels
- */
- prefix () {
- outbyte ('_');
- }
-
-
- /*
- * print any assembler stuff needed after all code
- *
- */
- trailer ()
- {
- ol (".end");
- }
-
- /*
- * function prologue
- */
- prologue ()
- {
- }
-
- /*
- * text (code) segment
- */
- gtext ()
- {
- ol (".text");
- }
-
- /*
- * data segment
- */
- gdata ()
- {
- ol (".data");
- }
-
- /*
- * Output the variable symbol at scptr as an extrn or a public
- */
- ppubext(scptr) char *scptr; {
- if (scptr[STORAGE] == STATIC) return;
- ot (".globl\t");
- prefix ();
- outstr (scptr);
- nl();
- }
-
- /*
- * Output the function symbol at scptr as an extrn or a public
- */
- fpubext(scptr) char *scptr; {
- ppubext(scptr);
- }
-
- /*
- * Output a decimal number to the assembler file
- */
- onum(num) int num; {
- outdec(num); /* pdp11 needs a "." here */
- outbyte('.');
- }
-
-
- /*
- * fetch a static memory cell into the primary register
- */
- getmem (sym)
- char *sym;
- {
- if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) {
- ot ("ldb\t");
- prefix ();
- outstr (sym + NAME);
- nl ();
- ot ("sex");
- nl ();
- } else {
- ot ("ldd\t");
- prefix ();
- outstr (sym + NAME);
- nl ();
- }
- }
-
- /*
- * fetch the address of the specified symbol into the primary register
- *
- */
- getloc (sym)
- char *sym;
- {
- if (sym[STORAGE] == LSTATIC) {
- immed();
- printlabel(glint(sym));
- nl();
- } else {
- ot ("leay\t");
- onum (glint(sym) - stkp);
- outstr ("(s)\n\ttfr\ty,d\n");
- }
- }
-
- /*
- * store the primary register into the specified static memory cell
- *
- */
- putmem (sym)
- char *sym;
- {
- if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) {
- ot ("stb\t");
- } else
- ot ("std\t");
- prefix ();
- outstr (sym + NAME);
- nl ();
- }
-
- /*
- * store the specified object type in the primary register
- * at the address on the top of the stack
- *
- */
- putstk (typeobj)
- char typeobj;
- {
- if (typeobj == CCHAR)
- ol ("stb\t@(s)++");
- else
- ol ("std\t@(s)++");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * fetch the specified object type indirect through the primary
- * register into the primary register
- *
- */
- indirect (typeobj)
- char typeobj;
- {
- ol("tfr\td,y");
- if (typeobj == CCHAR)
- ol ("ldb\t(y)\n\tsex");
- else
- ol ("ldd\t(y)");
- }
-
- /*
- * swap the primary and secondary registers
- *
- */
- swap ()
- {
- ol ("exg\td,x");
- }
-
- /*
- * print partial instruction to get an immediate value into
- * the primary register
- *
- */
- immed ()
- {
- ot ("ldd\t#");
- }
-
- /*
- * push the primary register onto the stack
- *
- */
- gpush ()
- {
- ol ("pshs\td");
- stkp = stkp - INTSIZE;
- }
-
- /*
- * pop the top of the stack into the secondary register
- *
- */
- gpop ()
- {
- ol ("puls\td");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * swap the primary register and the top of the stack
- *
- */
- swapstk ()
- {
- ol ("ldy\t(s)\nstd\t(s)\n\ttfr\ty,d");
- }
-
- /*
- * call the specified subroutine name
- *
- */
- gcall (sname)
- char *sname;
- {
- ot ("jsr\t");
- if (*sname == '^')
- outstr (++sname);
- else {
- prefix ();
- outstr (sname);
- }
- nl ();
- }
-
- /*
- * return from subroutine
- *
- */
- gret ()
- {
- ol ("rts");
- }
-
- /*
- * perform subroutine call to value on top of stack
- *
- */
- callstk ()
- {
- gpop();
- ol ("jsr\t(x)");
- }
-
- /*
- * jump to specified internal label number
- *
- */
- jump (label)
- int label;
- {
- ot ("lbra\t");
- printlabel (label);
- nl ();
- }
-
- /*
- * test the primary register and jump if false to label
- *
- */
- testjump (label, ft)
- int label,
- ft;
- {
- ol ("cmpd\t#0");
- if (ft)
- ot ("lbne\t");
- else
- ot ("lbeq\t");
- printlabel (label);
- nl ();
- }
-
- /*
- * print pseudo-op to define a byte
- *
- */
- defbyte ()
- {
- ot (".byte\t");
- }
-
- /*
- * print pseudo-op to define storage
- *
- */
- defstorage ()
- {
- ot (".blkb\t");
- }
-
- /*
- * print pseudo-op to define a word
- *
- */
- defword ()
- {
- ot (".word\t");
- }
-
- /*
- * modify the stack pointer to the new value indicated
- *
- */
- modstk (newstkp)
- int newstkp;
- {
- int k;
-
- k = galign(newstkp - stkp);
- if (k == 0)
- return (newstkp);
- ot ("leas\t");
- onum (k);
- outstr ("(s)\n");
- return (newstkp);
- }
-
- /*
- * multiply the primary register by INTSIZE
- */
- gaslint ()
- {
- ol ("aslb\n\trola");
- }
-
- /*
- * divide the primary register by INTSIZE
- */
- gasrint()
- {
- ol ("asra\n\trorb");
- }
-
- /*
- * Case jump instruction
- */
- gjcase() {
- ot ("jmp\tcase");
- nl ();
- }
-
- /*
- * add the primary and secondary registers
- * if lval2 is int pointer and lval is int, scale lval
- */
- gadd (lval, lval2) int *lval, *lval2;
- {
- if (dbltest (lval2, lval)) {
- ol ("asl\t1(s)\n\trol\t(s)");
- }
- ol ("addd\t(s)++");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * subtract the primary register from the secondary
- *
- */
- gsub ()
- {
- ol ("subd\t(s)++\n\tcoma\n\tcomb\n\taddd\t#1");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * multiply the primary and secondary registers
- * (result in primary)
- *
- */
- gmult ()
- {
- gcall ("^smul");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * divide the secondary register by the primary
- * (quotient in primary, remainder in secondary)
- *
- */
- gdiv ()
- {
- gcall ("^sdiv");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * compute the remainder (mod) of the secondary register
- * divided by the primary register
- * (remainder in primary, quotient in secondary)
- *
- */
- gmod ()
- {
- gcall ("^smod");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * inclusive 'or' the primary and secondary registers
- *
- */
- gor ()
- {
- ol ("ora\t(s)+\n\torb\t(s)+");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * exclusive 'or' the primary and secondary registers
- *
- */
- gxor ()
- {
- ol ("eora\t(s)+\n\teorb\t(s)+");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * 'and' the primary and secondary registers
- *
- */
- gand ()
- {
- ol ("anda\t(s)+\n\tandb\t(s)+");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * arithmetic shift right the secondary register the number of
- * times in the primary register
- * (results in primary register)
- *
- */
- gasr ()
- {
- gcall ("^asr");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * arithmetic shift left the secondary register the number of
- * times in the primary register
- * (results in primary register)
- *
- */
- gasl ()
- {
- gcall ("^asl");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * two's complement of primary register
- *
- */
- gneg ()
- {
- gcall ("^neg");
- }
-
- /*
- * logical complement of primary register
- *
- */
- glneg ()
- {
- gcall ("^lneg");
- }
-
- /*
- * one's complement of primary register
- *
- */
- gcom ()
- {
- ol ("coma\n\tcomb");
- }
-
- /*
- * convert primary register into logical value
- *
- */
- gbool ()
- {
- gcall ("^bool");
- }
- /*
- * increment the primary register by 1 if char, INTSIZE if
- * int
- */
- ginc (lval) int lval[];
- {
- if (lval[2] == CINT)
- ol ("addd\t#2");
- else
- ol ("addd\t#1");
- }
-
- /*
- * decrement the primary register by one if char, INTSIZE if
- * int
- */
- gdec (lval) int lval[];
- {
- if (lval[2] == CINT)
- ol ("subd\t#2");
- else
- ol ("subd\t#1");
- }
-
- /*
- * following are the conditional operators.
- * they compare the secondary register against the primary register
- * and put a literl 1 in the primary if the condition is true,
- * otherwise they clear the primary register
- *
- */
-
- /*
- * equal
- *
- */
- geq ()
- {
- gcall ("^eq");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * not equal
- *
- */
- gne ()
- {
- gcall ("^ne");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * less than (signed)
- *
- */
- glt ()
- {
- gcall ("^lt");
- stkp = stkp + INTSIZE;
- }
- /*
- * less than or equal (signed)
- *
- */
- gle ()
- {
- gcall ("^le");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * greater than (signed)
- *
- */
- ggt ()
- {
- gcall ("^gt");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * greater than or equal (signed)
- *
- */
- gge ()
- {
- gcall ("^ge");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * less than (unsigned)
- *
- */
- gult ()
- {
- gcall ("^ult");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * less than or equal (unsigned)
- *
- */
- gule ()
- {
- gcall ("^ule");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * greater than (unsigned)
- *
- */
- gugt ()
- {
- gcall ("^ugt");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * greater than or equal (unsigned)
- *
- */
- guge ()
- {
- gcall ("^uge");
- stkp = stkp + INTSIZE;
- }
-
- inclib() {
- #ifdef flex
- return("B.");
- #endif
- #ifdef unix
- return(INCDIR);
- #endif
- #ifdef cpm
- return("B:");
- #endif
- }
-
- /* Squirrel away argument count in a register that modstk/getloc/stloc
- doesn't touch.
- */
-
- gnargs(d)
- int d; {
- ot ("ldu\t#");
- onum(d);
- nl ();
- }
-
- assemble(s)
- char *s; {
- #ifdef ASNM
- char buf[100];
- strcpy(buf, ASNM);
- strcat(buf, " ");
- strcat(buf, s);
- buf[strlen(buf)-1] = 's';
- return(system(buf));
- #else
- return(0);
- #endif
- }
-
- link() {
- #ifdef LDNM
- fputs("I don't know how to link files yet\n", stderr);
- #else
- return(0);
- #endif
- }
- SHAR_EOF
- if test 9534 -ne "`wc -c < 'codeas09.c'`"
- then
- echo shar: error transmitting "'codeas09.c'" '(should have been 9534 characters)'
- fi
- fi
- echo shar: extracting "'codem68k.c'" '(11259 characters)'
- if test -f 'codem68k.c'
- then
- echo shar: will not over-write existing file "'codem68k.c'"
- else
- cat << \SHAR_EOF > 'codem68k.c'
- /* File codem68k.c: 1.2 (84/11/28,10:15:09) */
- /*% cc -O -c %
- *
- */
-
- #include <stdio.h>
- #include "defs.h"
- #include "data.h"
-
- #ifdef unix
- #ifdef m68k
- #define ASNM "as -o "
- #define LDNM "ld -o a.out /lib/crt0.o "
- #endif
- #ifdef pyr
- #define ASNM "/u1/cx/bin/m68kas -o "
- #define LDNM "/u1/cx/bin/m68kld -o a.out /u1/cx/lib/m68kcrt0.o "
- #endif
- #endif
-
- int needr0;
- int needh;
- /*
- * Some predefinitions:
- *
- * INTSIZE is the size of an integer in the target machine
- * BYTEOFF is the offset of an byte within an integer on the
- * target machine. (ie: 8080,pdp11 = 0, 6809 = 1,
- * 360 = 3)
- * This compiler assumes that an integer is the SAME length as
- * a pointer - in fact, the compiler uses INTSIZE for both.
- */
- #define INTSIZE 4
- #define BYTEOFF 3
-
- /*
- * print all assembler info before any code is generated
- *
- */
- header ()
- {
- outstr("#\tSmall C M68000\n#\tCoder (1.2,84/11/28)\n#");
- FEvers();
- nl ();
- ol ("global\tTlneg");
- ol ("global\tTcase");
- ol ("global\tTeq");
- ol ("global\tTne");
- ol ("global\tTlt");
- ol ("global\tTle");
- ol ("global\tTgt");
- ol ("global\tTge");
- ol ("global\tTult");
- ol ("global\tTule");
- ol ("global\tTugt");
- ol ("global\tTuge");
- ol ("global\tTbool");
- ol ("global\tTmult");
- ol ("global\tTdiv");
- ol ("global\tTmod");
- }
-
- nl()
- {
- if (needh) {
- ol ("word\t0");
- needh = 0;
- }
- if (needr0) {
- needr0 = 0;
- outstr(",%d0");
- }
- outbyte(EOL);
- }
-
- initmac() {
- defmac("m68k\t1");
- defmac("unix\t1");
- defmac("smallc\t1");
- }
-
- galign(t)
- int t;
- {
- int sign;
- if (t < 0) {
- sign = 1;
- t = -t;
- } else
- sign = 0;
- t = (t + INTSIZE - 1) & ~(INTSIZE - 1);
- t = sign? -t: t;
- return (t);
- }
-
-
-
- /*
- * return size of an integer
- */
- intsize() {
- return(INTSIZE);
- }
-
- /*
- * return offset of ls byte within word
- * (ie: 8080 & pdp11 is 0, 6809 is 1, 360 is 3)
- */
- byteoff() {
- return(BYTEOFF);
- }
-
- /*
- * Output internal generated label prefix
- */
- olprfix() {
- outstr("LL");
- }
-
- /*
- * Output a label definition terminator
- */
- col ()
- {
- outstr (":\n");
- }
-
- /*
- * begin a comment line for the assembler
- *
- */
- comment ()
- {
- outbyte ('#');
- }
-
- /*
- * Output a prefix in front of user labels
- */
- prefix () {
- /* outbyte ('_'); */
- }
-
-
- /*
- * print any assembler stuff needed after all code
- *
- */
- trailer ()
- {
- }
-
- /*
- * function prologue
- */
- prologue ()
- {
- /* this is where we'd put splimit stuff */
- }
-
- /*
- * text (code) segment
- */
- gtext ()
- {
- ol ("text");
- }
-
- /*
- * data segment
- */
- gdata ()
- {
- ol ("data");
- }
-
- /*
- * Output the variable symbol at scptr as an extrn or a public
- */
- ppubext(scptr) char *scptr; {
- if (scptr[STORAGE] == STATIC) return;
- ot ("global\t");
- prefix ();
- outstr (scptr);
- nl();
- }
-
- /*
- * Output the function symbol at scptr as an extrn or a public
- */
- fpubext(scptr) char *scptr; {
- ppubext(scptr);
- }
-
- /*
- * Output a decimal number to the assembler file
- */
- onum(num) int num; {
- outdec(num); /* pdp11 needs a "." here */
- }
-
-
- /*
- * fetch a static memory cell into the primary register
- */
- getmem (sym)
- char *sym;
- {
- int ischr;
- if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) {
- ischr = 1;
- ot ("mov.b\t");
- prefix ();
- outstr (sym + NAME);
- } else {
- ischr = 0;
- ot ("mov.l\t");
- prefix ();
- outstr (sym + NAME);
- }
- outstr(",%d0\n");
- if (ischr)
- ol ("ext.b\t%d0");
- }
-
- /*
- * fetch the address of the specified symbol into the primary register
- *
- */
- getloc (sym)
- char *sym;
- {
- if (sym[STORAGE] == LSTATIC) {
- immed();
- printlabel(glint(sym));
- nl();
- } else {
- ot ("lea.l\t");
- onum (glint(sym) - stkp);
- outstr (",%a0\n");
- ol ("mov.l\t%a0,%d0");
- }
- }
-
- /*
- * store the primary register into the specified static memory cell
- *
- */
- putmem (sym)
- char *sym;
- {
- if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) {
- ot ("mov.b\t%d0,");
- } else
- ot ("mov.l\t%d0,");
- prefix ();
- outstr (sym + NAME);
- nl ();
- }
-
- /*
- * store the specified object type in the primary register
- * at the address on the top of the stack
- *
- */
- putstk (typeobj)
- char typeobj;
- {
- ol ("mov.l\t(%sp)+,%a0");
- if (typeobj == CCHAR)
- ol ("mov.b\t%d0,(%a0)");
- else
- ol ("mov.l\t%d0,(%a0)");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * fetch the specified object type indirect through the primary
- * register into the primary register
- *
- */
- indirect (typeobj)
- char typeobj;
- {
- ol ("mov.l\t%d0,%a0");
- if (typeobj == CCHAR)
- ol ("mov.b\t(%a0),%d0");
- else
- ol ("mov.l\t(%a0),%d0");
- }
-
- /*
- * swap the primary and secondary registers
- *
- */
- swap ()
- {
- ol ("mov.l\t%d0,%d2\n\tmov.l\t%d1,%d0\n\tmov.l\t%d2,%d1");
- }
-
- /*
- * print partial instruction to get an immediate value into
- * the primary register
- *
- */
- immed ()
- {
- ot ("mov.l\t&");
- needr0 = 1;
- }
-
- /*
- * push the primary register onto the stack
- *
- */
- gpush ()
- {
- ol ("mov.l\t%d0,-(%sp)");
- stkp = stkp - INTSIZE;
- }
-
- /*
- * pop the top of the stack into the secondary register
- *
- */
- gpop ()
- {
- ol ("mov.l\t(%sp)+,%d1");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * swap the primary register and the top of the stack
- *
- */
- swapstk ()
- {
- ol ("mov.l\t(%sp)+,%d2\nmov.l\t%d0,-(%sp)\nmov.l\t%d2,%d0");
- }
-
- /*
- * call the specified subroutine name
- *
- */
- gcall (sname)
- char *sname;
- {
- if (*sname == '^') {
- ot ("jsr\tT");
- outstr (++sname);
- } else {
- ot ("jsr\t");
- prefix ();
- outstr (sname);
- }
- nl ();
- }
-
- /*
- * return from subroutine
- *
- */
- gret ()
- {
- ol ("rts");
- }
-
- /*
- * perform subroutine call to value on top of stack
- *
- */
- callstk ()
- {
- ol ("jsr\t(%sp)+");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * jump to specified internal label number
- *
- */
- jump (label)
- int label;
- {
- ot ("jmp\t");
- printlabel (label);
- nl ();
- }
-
- /*
- * test the primary register and jump if false to label
- *
- */
- testjump (label, ft)
- int label,
- ft;
- {
- ol ("cmp.l\t%d0,&0");
- if (ft)
- ot ("beq\t");
- else
- ot ("bne\t");
- printlabel (label);
- nl ();
- }
-
- /*
- * print pseudo-op to define a byte
- *
- */
- defbyte ()
- {
- ot ("byte\t");
- }
-
- /*
- * print pseudo-op to define storage
- *
- */
- defstorage ()
- {
- ot ("space\t");
- }
-
- /*
- * print pseudo-op to define a word
- *
- */
- defword ()
- {
- ot ("long\t");
- }
-
- /*
- * modify the stack pointer to the new value indicated
- *
- */
- modstk (newstkp)
- int newstkp;
- {
- int k;
-
- k = newstkp - stkp;
- if (k % INTSIZE)
- error("Bad stack alignment (compiler error)");
- if (k == 0)
- return (newstkp);
- ot ("add.l\t&");
- onum (k);
- outstr (",sp");
- nl();
- return (newstkp);
- }
-
- /*
- * multiply the primary register by INTSIZE
- */
- gaslint ()
- {
- ol ("asl.l\t&2,%d0");
- }
-
- /*
- * divide the primary register by INTSIZE
- */
- gasrint()
- {
- ol ("asr.l\t&2,%d0");
- }
-
- /*
- * Case jump instruction
- */
- gjcase() {
- gcall ("^case");
- }
-
- /*
- * add the primary and secondary registers
- * if lval2 is int pointer and lval is int, scale lval
- */
- gadd (lval, lval2) int *lval, *lval2;
- {
- if (dbltest (lval2, lval)) {
- ol ("asl.l\t&2,(%sp)");
- }
- ol ("add.l\t(%sp)+,%d0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * subtract the primary register from the secondary
- *
- */
- gsub ()
- {
- ol ("mov.l\t(%sp)+,%d2");
- ol ("sub.l\t%d0,%d2");
- ol ("mov.l\t%d2,%d0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * multiply the primary and secondary registers
- * (result in primary)
- *
- */
- gmult ()
- {
- gcall ("^mult");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * divide the secondary register by the primary
- * (quotient in primary, remainder in secondary)
- *
- */
- gdiv ()
- {
- gcall ("^div");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * compute the remainder (mod) of the secondary register
- * divided by the primary register
- * (remainder in primary, quotient in secondary)
- *
- */
- gmod ()
- {
- gcall ("^mod");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * inclusive 'or' the primary and secondary registers
- *
- */
- gor ()
- {
- ol ("or.l\t(%sp)+,%d0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * exclusive 'or' the primary and secondary registers
- *
- */
- gxor ()
- {
- ol ("mov.l\t(%sp)+,%d1");
- ol ("eor.l\t%d1,%d0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * 'and' the primary and secondary registers
- *
- */
- gand ()
- {
- ol ("and.l\t(%sp)+,%d0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * arithmetic shift right the secondary register the number of
- * times in the primary register
- * (results in primary register)
- *
- */
- gasr ()
- {
- ol ("mov.l\t(%sp)+,%d1");
- ol ("asr.l\t%d0,%d1");
- ol ("mov.l\t%d1,%d0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * arithmetic shift left the secondary register the number of
- * times in the primary register
- * (results in primary register)
- *
- */
- gasl ()
- {
- ol ("mov.l\t(%sp)+,%d1");
- ol ("asl.l\t%d0,%d1");
- ol ("mov.l\t%d1,%d0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * two's complement of primary register
- *
- */
- gneg ()
- {
- ol ("neg.l\t%d0");
- }
-
- /*
- * logical complement of primary register
- *
- */
- glneg ()
- {
- gcall ("^lneg");
- }
-
- /*
- * one's complement of primary register
- *
- */
- gcom ()
- {
- ol ("not\t%d0");
- }
-
- /*
- * convert primary register into logical value
- *
- */
- gbool ()
- {
- gcall ("^bool");
- }
- /*
- * increment the primary register by 1 if char, INTSIZE if
- * int
- */
- ginc (lval) int lval[];
- {
- if (lval[2] == CINT)
- ol ("addq.l\t&4,%d0");
- else
- ol ("addq.l\t&1,%d0");
- }
-
- /*
- * decrement the primary register by one if char, INTSIZE if
- * int
- */
- gdec (lval) int lval[];
- {
- if (lval[2] == CINT)
- ol ("subq.l\t&4,%d0");
- else
- ol ("subq.l\t&1,%d0");
- }
-
- /*
- * following are the conditional operators.
- * they compare the secondary register against the primary register
- * and put a literl 1 in the primary if the condition is true,
- * otherwise they clear the primary register
- *
- */
-
- /*
- * equal
- *
- */
- geq ()
- {
- gcall ("^eq");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * not equal
- *
- */
- gne ()
- {
- gcall ("^ne");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * less than (signed)
- *
- */
- glt ()
- {
- gcall ("^lt");
- stkp = stkp + INTSIZE;
- }
- /*
- * less than or equal (signed)
- *
- */
- gle ()
- {
- gcall ("^le");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * greater than (signed)
- *
- */
- ggt ()
- {
- gcall ("^gt");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * greater than or equal (signed)
- *
- */
- gge ()
- {
- gcall ("^ge");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * less than (unsigned)
- *
- */
- gult ()
- {
- gcall ("^ult");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * less than or equal (unsigned)
- *
- */
- gule ()
- {
- gcall ("^ule");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * greater than (unsigned)
- *
- */
- gugt ()
- {
- gcall ("^ugt");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * greater than or equal (unsigned)
- *
- */
- guge ()
- {
- gcall ("^uge");
- stkp = stkp + INTSIZE;
- }
-
- inclib() {
- #ifdef flex
- return("B.");
- #endif
- #ifdef unix
- return(INCDIR);
- #endif
- #ifdef cpm
- return("B:");
- #endif
- }
-
- /* Squirrel away argument count in a register that modstk/getloc/stloc
- doesn't touch.
- */
-
- gnargs(d)
- int d; {
- ot ("mov.l\t&");
- onum(d);
- outstr(",%d3\n");
- }
-
- #ifndef NOASLD
- char assems[400];
- int assinit;
- assemble(s)
- char *s; {
- #ifdef ASNM
- char cmd[100],buf[100];
- char *p;
- int ex, rc, delaft;
- #ifdef unix
- p = strrchr(s, '/');
- if (p)
- strcat(buf, p+1);
- else
- #endif
- strcat(buf, s);
- p = buf + strlen(buf) - 1;
- rc = typeof(s);
- delaft = (rc == 'c');
- if (rc == 'c' || rc == 's') {
- ex = 0;
- *p = 'o';
- } else
- ex = 1;
- if (!assinit) {
- strcat(assems, LDNM);
- assinit = 1;
- }
- strcat(assems, buf);
- strcat(assems, " ");
- if (ex)
- return(0);
- strcpy(cmd, ASNM);
- strcat(cmd, buf);
- strcat(cmd, " ");
- *p = 's';
- strcat(cmd, buf);
- rc = system(cmd);
- if (!rc && delaft)
- unlink(buf);
- return(rc);
- #else
- return(0);
- #endif
- }
-
- link() {
- #ifdef LDNM
- #ifdef unix
- #ifdef m68k
- strcat(assems, " -lc");
- #else
- strcat(assems, " /u1/cx/lib/libc.a");
- #endif
- #endif
- return(system(assems));
- #else
- return(0);
- #endif
- }
- #endif
- SHAR_EOF
- if test 11259 -ne "`wc -c < 'codem68k.c'`"
- then
- echo shar: error transmitting "'codem68k.c'" '(should have been 11259 characters)'
- fi
- fi
- echo shar: extracting "'codevax.c'" '(10274 characters)'
- if test -f 'codevax.c'
- then
- echo shar: will not over-write existing file "'codevax.c'"
- else
- cat << \SHAR_EOF > 'codevax.c'
- /* File codevax.c: 2.2 (84/08/31,10:05:16) */
- /*% cc -O -c %
- *
- */
-
- #include <stdio.h>
- #include "defs.h"
- #include "data.h"
-
- #ifdef vax
- #define ASNM "/bin/as"
- #define LDNM "/bin/ld"
- #endif
-
- /* Define ASNM and LDNM to the names of the assembler and linker
- respectively */
-
- int needr0;
- int needh;
- /*
- * Some predefinitions:
- *
- * INTSIZE is the size of an integer in the target machine
- * BYTEOFF is the offset of an byte within an integer on the
- * target machine. (ie: 8080,pdp11 = 0, 6809 = 1,
- * 360 = 3)
- * This compiler assumes that an integer is the SAME length as
- * a pointer - in fact, the compiler uses INTSIZE for both.
- */
- #define INTSIZE 4
- #define BYTEOFF 0
-
- /*
- * print all assembler info before any code is generated
- *
- */
- header ()
- {
- outstr("#\tSmall C VAX\n#\tCoder (2.4,84/11/27)\n#");
- FEvers();
- nl ();
- ol (".globl\tlneg");
- ol (".globl\tcase");
- ol (".globl\teq");
- ol (".globl\tne");
- ol (".globl\tlt");
- ol (".globl\tle");
- ol (".globl\tgt");
- ol (".globl\tge");
- ol (".globl\tult");
- ol (".globl\tule");
- ol (".globl\tugt");
- ol (".globl\tuge");
- ol (".globl\tbool");
- }
-
- nl()
- {
- if (needh) {
- ol (".word\t0");
- needh = 0;
- }
- if (needr0) {
- needr0 = 0;
- outstr(",r0");
- }
- outbyte(EOL);
- }
-
- initmac() {
- defmac("vax\t1");
- defmac("unix\t1");
- defmac("smallc\t1");
- }
-
- galign(t)
- int t;
- {
- int sign;
- if (t < 0) {
- sign = 1;
- t = -t;
- } else
- sign = 0;
- t = (t + INTSIZE - 1) & ~(INTSIZE - 1);
- t = sign? -t: t;
- return (t);
- }
-
-
-
- /*
- * return size of an integer
- */
- intsize() {
- return(INTSIZE);
- }
-
- /*
- * return offset of ls byte within word
- * (ie: 8080 & pdp11 is 0, 6809 is 1, 360 is 3)
- */
- byteoff() {
- return(BYTEOFF);
- }
-
- /*
- * Output internal generated label prefix
- */
- olprfix() {
- outstr("LL");
- }
-
- /*
- * Output a label definition terminator
- */
- col ()
- {
- outstr (":\n");
- }
-
- /*
- * begin a comment line for the assembler
- *
- */
- comment ()
- {
- outbyte ('#');
- }
-
- /*
- * Output a prefix in front of user labels
- */
- prefix () {
- outbyte ('_');
- }
-
-
- /*
- * print any assembler stuff needed after all code
- *
- */
- trailer ()
- {
- }
-
- /*
- * function prologue
- */
- prologue ()
- {
- ol (".align\t1");
- }
-
- /*
- * text (code) segment
- */
- gtext ()
- {
- ol (".text");
- }
-
- /*
- * data segment
- */
- gdata ()
- {
- ol (".data");
- }
-
- /*
- * Output the variable symbol at scptr as an extrn or a public
- */
- ppubext(scptr) char *scptr; {
- if (scptr[STORAGE] == STATIC) return;
- ot (".globl\t");
- prefix ();
- outstr (scptr);
- nl();
- }
-
- /*
- * Output the function symbol at scptr as an extrn or a public
- */
- fpubext(scptr) char *scptr; {
- ppubext(scptr);
- }
-
- /*
- * Output a decimal number to the assembler file
- */
- onum(num) int num; {
- outdec(num); /* pdp11 needs a "." here */
- }
-
-
- /*
- * fetch a static memory cell into the primary register
- */
- getmem (sym)
- char *sym;
- {
- if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) {
- ot ("cvtbl\t");
- prefix ();
- outstr (sym + NAME);
- } else {
- ot ("movl\t");
- prefix ();
- outstr (sym + NAME);
- }
- outstr(",r0\n");
- }
-
- /*
- * fetch the address of the specified symbol into the primary register
- *
- */
- getloc (sym)
- char *sym;
- {
- if (sym[STORAGE] == LSTATIC) {
- immed();
- printlabel(glint(sym));
- nl();
- } else {
- ot ("moval\t");
- onum (glint(sym) - stkp);
- outstr ("(sp),r0\n");
- }
- }
-
- /*
- * store the primary register into the specified static memory cell
- *
- */
- putmem (sym)
- char *sym;
- {
- if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) {
- ot ("cvtlb\tr0,");
- } else
- ot ("movl\tr0,");
- prefix ();
- outstr (sym + NAME);
- nl ();
- }
-
- /*
- * store the specified object type in the primary register
- * at the address on the top of the stack
- *
- */
- putstk (typeobj)
- char typeobj;
- {
- if (typeobj == CCHAR)
- ol ("cvtlb\tr0,*(sp)+");
- else
- ol ("movl\tr0,*(sp)+");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * fetch the specified object type indirect through the primary
- * register into the primary register
- *
- */
- indirect (typeobj)
- char typeobj;
- {
- if (typeobj == CCHAR)
- ol ("cvtbl\t(r0),r0");
- else
- ol ("movl\t(r0),r0");
- }
-
- /*
- * swap the primary and secondary registers
- *
- */
- swap ()
- {
- ol ("movl\tr0,r2\n\tmovl\tr1,r0\n\tmovl\tr2,r1");
- }
-
- /*
- * print partial instruction to get an immediate value into
- * the primary register
- *
- */
- immed ()
- {
- ot ("movl\t$");
- needr0 = 1;
- }
-
- /*
- * push the primary register onto the stack
- *
- */
- gpush ()
- {
- ol ("pushl\tr0");
- stkp = stkp - INTSIZE;
- }
-
- /*
- * pop the top of the stack into the secondary register
- *
- */
- gpop ()
- {
- ol ("movl\t(sp)+,r1");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * swap the primary register and the top of the stack
- *
- */
- swapstk ()
- {
- ol ("popl\tr2\npushl\tr0\nmovl\tr2,r0");
- }
-
- /*
- * call the specified subroutine name
- *
- */
- gcall (sname)
- char *sname;
- {
- if (*sname == '^') {
- ot ("jsb\t");
- outstr (++sname);
- } else {
- ot ("jsb\t");
- prefix ();
- outstr (sname);
- }
- nl ();
- }
-
- /*
- * return from subroutine
- *
- */
- gret ()
- {
- ol ("rsb");
- }
-
- /*
- * perform subroutine call to value on top of stack
- *
- */
- callstk ()
- {
- ol ("jsb\t(sp)+");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * jump to specified internal label number
- *
- */
- jump (label)
- int label;
- {
- ot ("jmp\t");
- printlabel (label);
- nl ();
- }
-
- /*
- * test the primary register and jump if false to label
- *
- */
- testjump (label, ft)
- int label,
- ft;
- {
- ol ("cmpl\tr0,$0");
- if (ft)
- ot ("jneq\t");
- else
- ot ("jeql\t");
- printlabel (label);
- nl ();
- }
-
- /*
- * print pseudo-op to define a byte
- *
- */
- defbyte ()
- {
- ot (".byte\t");
- }
-
- /*
- * print pseudo-op to define storage
- *
- */
- defstorage ()
- {
- ot (".space\t");
- }
-
- /*
- * print pseudo-op to define a word
- *
- */
- defword ()
- {
- ot (".long\t");
- }
-
- /*
- * modify the stack pointer to the new value indicated
- *
- */
- modstk (newstkp)
- int newstkp;
- {
- int k;
-
- k = newstkp - stkp;
- if (k % INTSIZE)
- error("Bad stack alignment (compiler error)");
- if (k == 0)
- return (newstkp);
- ot ("addl2\t$");
- onum (k);
- outstr (",sp");
- nl();
- return (newstkp);
- }
-
- /*
- * multiply the primary register by INTSIZE
- */
- gaslint ()
- {
- ol ("ashl\t$2,r0,r0");
- }
-
- /*
- * divide the primary register by INTSIZE
- */
- gasrint()
- {
- ol ("ashl\t$-2,r0,r0");
- }
-
- /*
- * Case jump instruction
- */
- gjcase() {
- ot ("jmp\tcase");
- nl ();
- }
-
- /*
- * add the primary and secondary registers
- * if lval2 is int pointer and lval is int, scale lval
- */
- gadd (lval, lval2) int *lval, *lval2;
- {
- if (dbltest (lval2, lval)) {
- ol ("ashl\t$2,(sp),(sp)");
- }
- ol ("addl2\t(sp)+,r0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * subtract the primary register from the secondary
- *
- */
- gsub ()
- {
- ol ("subl3\tr0,(sp)+,r0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * multiply the primary and secondary registers
- * (result in primary)
- *
- */
- gmult ()
- {
- ol ("mull2\t(sp)+,r0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * divide the secondary register by the primary
- * (quotient in primary, remainder in secondary)
- *
- */
- gdiv ()
- {
- ol ("divl3\tr0,(sp)+,r0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * compute the remainder (mod) of the secondary register
- * divided by the primary register
- * (remainder in primary, quotient in secondary)
- *
- */
- gmod ()
- {
- ol ("movl\t(sp)+,r2\n\tmovl\t$0,r3\nediv\tr0,r2,r1,r0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * inclusive 'or' the primary and secondary registers
- *
- */
- gor ()
- {
- ol ("bisl2\t(sp)+,r0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * exclusive 'or' the primary and secondary registers
- *
- */
- gxor ()
- {
- ol ("xorl2\t(sp)+,r0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * 'and' the primary and secondary registers
- *
- */
- gand ()
- {
- ol ("mcoml\t(sp)+,r1\n\tbicl2\tr1,r0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * arithmetic shift right the secondary register the number of
- * times in the primary register
- * (results in primary register)
- *
- */
- gasr ()
- {
- ol("mnegl\tr0,r0\n\tashl\tr0,(sp)+,r0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * arithmetic shift left the secondary register the number of
- * times in the primary register
- * (results in primary register)
- *
- */
- gasl ()
- {
- ol ("ashl\tr0,(sp)+,r0");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * two's complement of primary register
- *
- */
- gneg ()
- {
- ol ("mnegl\tr0,r0");
- }
-
- /*
- * logical complement of primary register
- *
- */
- glneg ()
- {
- gcall ("^lneg");
- }
-
- /*
- * one's complement of primary register
- *
- */
- gcom ()
- {
- ol ("mcoml\tr0,r0");
- }
-
- /*
- * convert primary register into logical value
- *
- */
- gbool ()
- {
- gcall ("^bool");
- }
- /*
- * increment the primary register by 1 if char, INTSIZE if
- * int
- */
- ginc (lval) int lval[];
- {
- if (lval[2] == CINT)
- ol ("addl2\t$4,r0");
- else
- ol ("incl\tr0");
- }
-
- /*
- * decrement the primary register by one if char, INTSIZE if
- * int
- */
- gdec (lval) int lval[];
- {
- if (lval[2] == CINT)
- ol ("subl2\t$4,r0");
- else
- ol ("decl\tr0");
- }
-
- /*
- * following are the conditional operators.
- * they compare the secondary register against the primary register
- * and put a literl 1 in the primary if the condition is true,
- * otherwise they clear the primary register
- *
- */
-
- /*
- * equal
- *
- */
- geq ()
- {
- gcall ("^eq");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * not equal
- *
- */
- gne ()
- {
- gcall ("^ne");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * less than (signed)
- *
- */
- glt ()
- {
- gcall ("^lt");
- stkp = stkp + INTSIZE;
- }
- /*
- * less than or equal (signed)
- *
- */
- gle ()
- {
- gcall ("^le");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * greater than (signed)
- *
- */
- ggt ()
- {
- gcall ("^gt");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * greater than or equal (signed)
- *
- */
- gge ()
- {
- gcall ("^ge");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * less than (unsigned)
- *
- */
- gult ()
- {
- gcall ("^ult");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * less than or equal (unsigned)
- *
- */
- gule ()
- {
- gcall ("^ule");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * greater than (unsigned)
- *
- */
- gugt ()
- {
- gcall ("^ugt");
- stkp = stkp + INTSIZE;
- }
-
- /*
- * greater than or equal (unsigned)
- *
- */
- guge ()
- {
- gcall ("^uge");
- stkp = stkp + INTSIZE;
- }
-
- /* Squirrel away argument count in a register that modstk
- doesn't touch.
- */
-
- gnargs(d)
- int d; {
- ot ("movl\t$");
- onum(d);
- outstr (",r6\n");
- }
-
- inclib() {
- #ifdef flex
- return("B.");
- #endif
- #ifdef unix
- return(INCDIR);
- #endif
- #ifdef cpm
- return("B:");
- #endif
- }
-
- assemble(s)
- char *s; {
- #ifdef ASNM
- char buf[100];
- strcpy(buf, ASNM);
- strcat(buf, " -o ");
- strcat(buf, s);
- buf[strlen(buf)-1] = 'o';
- strcat(buf, " ");
- strcat(buf, s);
- buf[strlen(buf)-1] = 's';
- return(system(buf));
- #else
- return(0);
- #endif
- }
-
- link() {
- #ifdef LDNM
- fputs("I don't know how to link files yet\n", stderr);
- #else
- return(0);
- #endif
- }
- SHAR_EOF
- if test 10274 -ne "`wc -c < 'codevax.c'`"
- then
- echo shar: error transmitting "'codevax.c'" '(should have been 10274 characters)'
- fi
- fi
- echo shar: extracting "'data.c'" '(722 characters)'
- if test -f 'data.c'
- then
- echo shar: will not over-write existing file "'data.c'"
- else
- cat << \SHAR_EOF > 'data.c'
- /* File data.c: 2.2 (84/11/27,16:26:13) */
- /*% cc -O -c %
- *
- */
-
- #include <stdio.h>
- #include "defs.h"
-
- /* storage words */
-
- char symtab[SYMTBSZ];
- char *glbptr, *rglbptr, *locptr;
- int ws[WSTABSZ];
- int *wsptr;
- int swstcase[SWSTSZ];
- int swstlab[SWSTSZ];
- int swstp;
- char litq[LITABSZ];
- int litptr;
- char macq[MACQSIZE];
- int macptr;
- char line[LINESIZE];
- char mline[LINESIZE];
- int lptr, mptr;
-
- /* miscellaneous storage */
-
- int nxtlab,
- litlab,
- stkp,
- argstk,
- ncmp,
- errcnt,
- glbflag,
- ctext,
- cmode,
- lastst;
-
- FILE *input, *input2, *output;
- FILE *inclstk[INCLSIZ];
- int inclsp;
- char fname[20];
-
- char quote[2];
- char *cptr;
- int *iptr;
- int fexitlab;
- int iflevel, skiplevel;
- int errfile;
- int sflag;
- int cflag;
- int errs;
- int aflag;
- SHAR_EOF
- if test 722 -ne "`wc -c < 'data.c'`"
- then
- echo shar: error transmitting "'data.c'" '(should have been 722 characters)'
- fi
- fi
- echo shar: extracting "'data.h'" '(807 characters)'
- if test -f 'data.h'
- then
- echo shar: will not over-write existing file "'data.h'"
- else
- cat << \SHAR_EOF > 'data.h'
- /* File data.h: 2.2 (84/11/27,16:26:11) */
-
- /* storage words */
-
- extern char symtab[];
- extern char *glbptr, *rglbptr, *locptr;
- extern int ws[];
- extern int *wsptr;
- extern int swstcase[];
- extern int swstlab[];
- extern int swstp;
- extern char litq[];
- extern int litptr;
- extern char macq[];
- extern int macptr;
- extern char line[];
- extern char mline[];
- extern int lptr, mptr;
-
- /* miscellaneous storage */
-
- extern int nxtlab,
- litlab,
- stkp,
- argstk,
- ncmp,
- errcnt,
- glbflag,
- ctext,
- cmode,
- lastst;
-
- extern FILE *input, *input2, *output;
- extern FILE *inclstk[];
- extern int inclsp;
- extern char fname[];
-
- extern char quote[];
- extern char *cptr;
- extern int *iptr;
- extern int fexitlab;
- extern int iflevel, skiplevel;
- extern int errfile;
- extern int sflag;
- extern int cflag;
- extern int errs;
- extern int aflag;
- SHAR_EOF
- if test 807 -ne "`wc -c < 'data.h'`"
- then
- echo shar: error transmitting "'data.h'" '(should have been 807 characters)'
- fi
- fi
- exit 0
- # End of shell archive
-